using System;
using System.Collections.Generic;
using System.Configuration.Install;
using System.Linq;
using System.Reflection;
using System.ServiceProcess;
using System.Text;

namespace Gko.WindowsService
{
	public static class ServiceExtensions
	{
		private static string GetRunMode()
		{
			return "console";
		}

		public static void StartService(this IServiceHelper helper, string[] args)
		{
			try {
				if (args.Length > 0 && args[0].IndexOfAny(new[] { '-', '/' }) == 0) {
					switch (args[0].Substring(1).ToLower()) {
						case "debug":
						case "d": {
								var serviceParams = new string[args.Length - 1];
								Array.Copy(args, 1, serviceParams, 0, serviceParams.Length);
								Console.WriteLine("Starting service {0} in {1} mode...", helper.Service.ServiceName, GetRunMode());
								helper.Start(serviceParams);
								Console.WriteLine("Service started");
								Console.WriteLine("Press any key to stop service...");
								Console.ReadKey();
								helper.Stop();
								Console.WriteLine("Service stopped");
								Console.WriteLine("Press any key to continue...");
								Console.ReadKey();
								return;
							}
						case "install":
						case "i":
							ManagedInstallerClass.InstallHelper(new[] { Assembly.GetEntryAssembly().Location });
							return;

						case "uninstall":
						case "u":
							ManagedInstallerClass.InstallHelper(new[] { "-u", Assembly.GetEntryAssembly().Location });
							return;

						case "start":
							Console.WriteLine("Starting service {0}...", helper.Service.ServiceName);
							using (var controller = new ServiceController(helper.Service.ServiceName)) {
								controller.Start();
								controller.WaitForStatus(ServiceControllerStatus.Running);
							}
							Console.WriteLine("Service started");
							return;

						case "stop":
							Console.WriteLine("Stoping service {0}...", helper.Service.ServiceName);
							using (var controller = new ServiceController(helper.Service.ServiceName)) {
								controller.Stop();
								controller.WaitForStatus(ServiceControllerStatus.Stopped);
							}
							Console.WriteLine("Service stopped");
							return;

						case "r":
						case "restart":
							Console.WriteLine("Restarting service {0}...", helper.Service.ServiceName);
							using (var controller = new ServiceController(helper.Service.ServiceName)) {
								controller.Stop();
								controller.WaitForStatus(ServiceControllerStatus.Stopped);
								Console.WriteLine("Service stopped");
								controller.Start();
								controller.WaitForStatus(ServiceControllerStatus.Running);
							}
							Console.WriteLine("Service started");
							return;

						case "s":
							using (var controller = new ServiceController(helper.Service.ServiceName)) {
								controller.Refresh();
								switch (controller.Status) {
									case ServiceControllerStatus.Stopped:
										Console.WriteLine("Starting service {0}...", helper.Service.ServiceName);
										controller.Start();
										controller.WaitForStatus(ServiceControllerStatus.Running);
										Console.WriteLine("Service started");
										break;

									case ServiceControllerStatus.Running:
										Console.WriteLine("Stoping service {0}...", helper.Service.ServiceName);
										controller.Stop();
										controller.WaitForStatus(ServiceControllerStatus.Stopped);
										Console.WriteLine("Service stopped");
										break;
								}
							}
							return;
						default:
							break;
					}
				}

				ServiceBase.Run(helper.Service);

			} catch (Exception e) {
				Console.WriteLine(e);
			}
		}
	}
}